package com.example.plantuml;

import com.example.plantuml.docx.DocxPlantUmlConverter;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.io.File;
import java.util.prefs.Preferences;

public class UiFrame {
    private final JFrame frame;
    private final JTextField serverField;
    private final JTextField fileField;
    private final JTextArea logArea;
    private final Preferences prefs = Preferences.userNodeForPackage(UiFrame.class);
    private static final String PREF_LAST_PATH = "lastDocxPath";
    private static final String PREF_LAST_DIR = "lastDocxDir";

    public UiFrame() {
        frame = new JFrame("PlantUML DOCX Converter");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(700, 400);
        frame.setLocationRelativeTo(null);

        JPanel panel = new JPanel(new BorderLayout(10, 10));
        JPanel top = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(5,5,5,5);
        c.gridx = 0; c.gridy = 0; c.anchor = GridBagConstraints.EAST;
        top.add(new JLabel("PlantUML Server:"), c);
        String localBase = LocalPlantUmlServerLauncher.startIfPossible(9996);
        String defaultServer = localBase != null ? localBase : "https://www.plantuml.com/plantuml";
        serverField = new JTextField(defaultServer, 40);
        c.gridx = 1; c.gridy = 0; c.anchor = GridBagConstraints.WEST;
        top.add(serverField, c);

        c.gridx = 0; c.gridy = 1; c.anchor = GridBagConstraints.EAST;
        top.add(new JLabel("DOCX File:"), c);
        fileField = new JTextField(40);
        c.gridx = 1; c.gridy = 1; c.anchor = GridBagConstraints.WEST;
        top.add(fileField, c);
        JButton browse = new JButton("Browse");
        c.gridx = 2; c.gridy = 1; c.anchor = GridBagConstraints.WEST;
        top.add(browse, c);

        JButton convert = new JButton("Start Conversion");
        c.gridx = 1; c.gridy = 2; c.anchor = GridBagConstraints.WEST;
        top.add(convert, c);

        panel.add(top, BorderLayout.NORTH);
        logArea = new JTextArea();
        logArea.setEditable(false);
        panel.add(new JScrollPane(logArea), BorderLayout.CENTER);

        frame.setContentPane(panel);

        browse.addActionListener(e -> onBrowse());
        convert.addActionListener(e -> onConvert());

        // Prefill last used DOCX path if available
        String lastPath = prefs.get(PREF_LAST_PATH, "");
        if (!lastPath.isEmpty()) {
            fileField.setText(lastPath);
        }
    }

    public void showWindow() {
        SwingUtilities.invokeLater(() -> frame.setVisible(true));
    }

    private void onBrowse() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new FileNameExtensionFilter("Word DOCX", "docx"));
        String lastDir = prefs.get(PREF_LAST_DIR, "");
        if (!lastDir.isEmpty()) {
            File dir = new File(lastDir);
            if (dir.exists() && dir.isDirectory()) {
                chooser.setCurrentDirectory(dir);
            }
        }
        int r = chooser.showOpenDialog(frame);
        if (r == JFileChooser.APPROVE_OPTION) {
            File selected = chooser.getSelectedFile();
            fileField.setText(selected.getAbsolutePath());
            // Save preferences for next time
            prefs.put(PREF_LAST_PATH, selected.getAbsolutePath());
            if (selected.getParentFile() != null) {
                prefs.put(PREF_LAST_DIR, selected.getParentFile().getAbsolutePath());
            }
        }
    }

    private void onConvert() {
        String server = serverField.getText().trim();
        String path = fileField.getText().trim();
        if (path.isEmpty()) {
            appendLog("Please select a DOCX file.");
            return;
        }
        File in = new File(path);
        if (!in.exists()) {
            appendLog("File not found: " + in.getAbsolutePath());
            return;
        }
        // Save last used file and directory (also handles manual edits)
        prefs.put(PREF_LAST_PATH, in.getAbsolutePath());
        if (in.getParentFile() != null) {
            prefs.put(PREF_LAST_DIR, in.getParentFile().getAbsolutePath());
        }
        File out = ensureUniqueFile(in.getParentFile(), stripExtension(in.getName()) + "_converted", ".docx");
        appendLog("Converting: " + in.getAbsolutePath());
        setControlsEnabled(false);
        new Thread(() -> {
            try {
                PlantUmlClient client = new PlantUmlClient(server);
                DocxPlantUmlConverter converter = new DocxPlantUmlConverter(client);
                converter.setProgressListener(this::appendLog);
                converter.convert(in, out);
                appendLog("Done -> " + out.getAbsolutePath());
                showSuccessDialog(out);
            } catch (Exception ex) {
                appendLog("Error: " + ex.getMessage());
            } finally {
                setControlsEnabled(true);
            }
        }).start();
    }

    private static String stripExtension(String name) {
        int idx = name.lastIndexOf('.')
                ;
        return idx >= 0 ? name.substring(0, idx) : name;
    }

    private void appendLog(String s) {
        SwingUtilities.invokeLater(() -> {
            logArea.append(s + "\n");
        });
    }

    private void setControlsEnabled(boolean enabled) {
        SwingUtilities.invokeLater(() -> {
            frame.setCursor(enabled ? Cursor.getDefaultCursor() : Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            for (Component comp : frame.getContentPane().getComponents()) {
                comp.setEnabled(enabled);
            }
        });
    }

    private void showSuccessDialog(File outFile) {
        SwingUtilities.invokeLater(() -> {
            Object[] options = {"打开文件夹", "确定"};
            int res = JOptionPane.showOptionDialog(
                    frame,
                    "转换完成：\n" + outFile.getName(),
                    "完成",
                    JOptionPane.DEFAULT_OPTION,
                    JOptionPane.INFORMATION_MESSAGE,
                    null,
                    options,
                    options[0]
            );
            if (res == 0) {
                openFolderContaining(outFile);
            }
        });
    }

    private void openFolderContaining(File file) {
        try {
            String os = System.getProperty("os.name", "").toLowerCase();
            if (os.contains("win")) {
                String cmd = "explorer.exe /select,\"" + file.getAbsolutePath().replace('/', '\\') + "\"";
                Runtime.getRuntime().exec(cmd);
                return;
            }
            if (Desktop.isDesktopSupported()) {
                Desktop.getDesktop().open(file.getParentFile());
            }
        } catch (Exception e) {
            appendLog("Open folder failed: " + e.getMessage());
        }
    }

    private static File ensureUniqueFile(File dir, String baseName, String extension) {
        File candidate = new File(dir, baseName + extension);
        int index = 1;
        while (candidate.exists()) {
            candidate = new File(dir, baseName + " (" + index + ")" + extension);
            index++;
        }
        return candidate;
    }
}


